package cn.sunflower.common.jwt.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;

/**
 * <p>
 * 日期工具类
 * java8 java.time包实现
 */
public class DateTimeUtil {

	public static final String DEFAULT_DATE_TIME_FORMATTER = "yyyy-MM-dd HH:mm:ss";

	public static final String DATE_FORMATTER = "yyyyMMdd";

	/**
	 * 格式化指定日期
	 *
	 * @param formatString 格式
	 * @param date         时间
	 * @return 格式化后时间
	 */
	public static String format(String formatString, Date date) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatString);
		return simpleDateFormat.format(date);
	}

	/**
	 * 解析日期
	 *
	 * @param date         日期字符串
	 * @param formatString 格式
	 * @return date
	 * @throws ParseException
	 */
	public static Date format(String date, String formatString) throws ParseException {
		SimpleDateFormat format = new SimpleDateFormat(formatString, Locale.CHINA);
		return format.parse(date);
	}

	/**
	 * 获取当前日期时间字符串
	 *
	 * @param formatter 格式化
	 * @return String
	 */
	public static String getCurrentDateTimeAsString(DateTimeFormatter formatter) {
		LocalDateTime currentDateTime = LocalDateTime.now();
		if (null == formatter) {
			formatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER);
		}
		return currentDateTime.format(formatter);
	}

	/**
	 * 获取当前日期字符串
	 *
	 * @param formatter 格式化
	 * @return String
	 */
	public static String getCurrentDateAsString(DateTimeFormatter formatter) {
		LocalDateTime currentDateTime = LocalDateTime.now();
		if (null == formatter) {
			formatter = DateTimeFormatter.ofPattern(DATE_FORMATTER);
		}
		return currentDateTime.format(formatter);
	}

	/**
	 * 转换Date为String
	 *
	 * @param formatter 格式化
	 * @return String
	 */
	public static String convertDateToString(DateTimeFormatter formatter, Date date) {
		if (null == formatter) {
			formatter = DateTimeFormatter.ofPattern(DATE_FORMATTER);
		}
		Instant instant = date.toInstant();
		ZoneId zoneId = ZoneId.systemDefault();
		// atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
		LocalDate localDate = instant.atZone(zoneId).toLocalDate();
		return localDate.format(formatter);
	}

	/**
	 * 获取当前日期时间
	 *
	 * @param formatter 格式化
	 * @return LocalDateTime
	 */
	public static LocalDateTime getCurrentLocalDateTime(DateTimeFormatter formatter) {
		String text = getCurrentDateTimeAsString(null);
		if (null == formatter) {
			formatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER);
		}
		return LocalDateTime.parse(text, formatter);
	}

	/**
	 * 获取当前日期时间
	 *
	 * @param formatter 格式化
	 * @return Date
	 */
	public static Date getCurrentDate(DateTimeFormatter formatter) {
		LocalDateTime parse = getCurrentLocalDateTime(formatter);
		return convertLocalDateTimeToDate(parse);
	}

	/**
	 * 转换java8的LocalDateTime为Date对象
	 *
	 * @param localDateTime java8
	 * @return Date
	 */
	public static Date convertLocalDateTimeToDate(LocalDateTime localDateTime) {
		ZoneId zoneId = ZoneId.systemDefault();
		ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
		return Date.from(zonedDateTime.toInstant());
	}

	/**
	 * 在当前时间加秒数
	 *
	 * @param second 秒(可为负数)
	 * @return 日期
	 */
	public static Date plusSecondBaseOnCurrentDate(int second) {
		LocalDateTime currentLocalDateTime = getCurrentLocalDateTime(null);
		LocalDateTime plusSeconds = currentLocalDateTime.plusSeconds(second);
		return convertLocalDateTimeToDate(plusSeconds);
	}

	/**
	 * 在当前时间加分钟
	 *
	 * @param min 分钟(可为负数)
	 * @return 日期
	 */
	public static Date plusMinBaseOnCurrentDate(int min) {
		LocalDateTime currentLocalDateTime = getCurrentLocalDateTime(null);
		LocalDateTime plusMin = currentLocalDateTime.plusMinutes(min);
		return convertLocalDateTimeToDate(plusMin);
	}

	/**
	 * 在当前时间加小时
	 *
	 * @param hour 小时(可为负数)
	 * @return 日期
	 */
	public static Date plusHourBaseOnCurrentDate(int hour) {
		LocalDateTime currentLocalDateTime = getCurrentLocalDateTime(null);
		LocalDateTime plusHours = currentLocalDateTime.plusHours(hour);
		return convertLocalDateTimeToDate(plusHours);
	}

	/**
	 * 在当前时间加小时
	 *
	 * @param day 天(可为负数)
	 * @return 日期
	 */
	public static Date plusDayBaseOnCurrentDate(int day) {
		LocalDateTime currentLocalDateTime = getCurrentLocalDateTime(null);
		LocalDateTime plusHours = currentLocalDateTime.plusDays(day);
		return convertLocalDateTimeToDate(plusHours);
	}

	/**
	 * 获取第二天的凌晨三点 - 主要用于JWT过期时间
	 *
	 * @return 日期
	 */
	public static Date getThreeOclockAMOfTheNextDay() {
		LocalDateTime currentLocalDateTime = getCurrentLocalDateTime(null);
		LocalDateTime nextDay = currentLocalDateTime.plusDays(1);
		LocalDateTime threeOclockAMOfTheNextDay = LocalDateTime.of(nextDay.getYear(), nextDay.getMonth(), nextDay.getDayOfMonth(), 3, 0, 0);
		return convertLocalDateTimeToDate(threeOclockAMOfTheNextDay);
	}

	/**
	 * 获取第七天的凌晨三点 - 主要用于JWT过期时间
	 *
	 * @return 日期
	 */
	public static Date getThreeOclockAMOfSeventhDay() {
		LocalDateTime currentLocalDateTime = getCurrentLocalDateTime(null);
		LocalDateTime nextDay = currentLocalDateTime.plusDays(7);
		LocalDateTime threeOclockAMOfSeventhDay = LocalDateTime.of(nextDay.getYear(), nextDay.getMonth(), nextDay.getDayOfMonth(), 3, 0, 0);
		return convertLocalDateTimeToDate(threeOclockAMOfSeventhDay);
	}

}
